package tests.jdl.tokenization.states;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import jdl.tokenization.Token;
import jdl.tokenization.TokenType;
import jdl.tokenization.states.IState;
import jdl.tokenization.states.InitialState;
import jdl.tokenization.states.NumberState;
import jdl.tokenization.states.WordState;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class InitialState_Test {
	private List<Token> tokens;
	private Hashtable<Character, TokenType> hashtable;
	private IState state;

	@Before
	public void setUp() {
		tokens = new ArrayList<Token>();
		hashtable = new Hashtable<Character, TokenType>();
		hashtable.put('0', TokenType.NUMBER);
		hashtable.put('(', TokenType.LEFT_BRACKET);
		hashtable.put(')', TokenType.RIGHT_BRACKET);
		state = new InitialState(tokens, hashtable);
	}

	@Test
	public void getNextState() {
		Assert.assertTrue(state.getNextState() instanceof InitialState);
	}

	@Test
	public void analyzeSymbol_SymbolIsLetter_CheckNextState() {
		state.analyzeSymbol('j');
		Assert.assertTrue(state.getNextState() instanceof WordState);
	}

	@Test
	public void analyzeSymbol_symbolIsWhiteSpace_checkNextState() {
		state.analyzeSymbol(' ');
		Assert.assertTrue(state.getNextState() instanceof InitialState);
	}

	@Test
	public void analyzeSymbol_SymbolIsLetter_endOfSymbols() {
		state.analyzeSymbol('n');
		state = state.getNextState();
		state.endOfSymbols();

		Assert.assertEquals(1, tokens.size());
		Token token = tokens.get(0);
		Assert.assertEquals("n", token.getContent());
		Assert.assertEquals(TokenType.WORD, token.getTokenType());
	}

	@Test
	public void analyzeSymbol_SymbolIsNumber_endOfSymbols() {
		state.analyzeSymbol('0');
		state = state.getNextState();
		state.endOfSymbols();

		Assert.assertEquals(1, tokens.size());
		Token token = tokens.get(0);
		Assert.assertEquals("0", token.getContent());
		Assert.assertEquals(TokenType.NUMBER, token.getTokenType());
	}

	@Test
	public void analyzeSymbol_SymbolIsNumber() {
		state.analyzeSymbol('0');
		Assert.assertTrue(state.getNextState() instanceof NumberState);
	}

	@Test
	public void analyzeSymbol_SymbolIsRightBracket_CheckNextState() {
		state.analyzeSymbol(')');
		Assert.assertTrue(state.getNextState() instanceof InitialState);
	}

	@Test
	public void analyzeSymbol_SymbolIsRightBracket_endOfSymbols() {
		state.analyzeSymbol(')');
		Assert.assertTrue(state.getNextState() instanceof InitialState);
		state.endOfSymbols();
		Assert.assertEquals(1, tokens.size());
		Token token = tokens.get(0);
		Assert.assertEquals(")", token.getContent());
		Assert.assertEquals(TokenType.RIGHT_BRACKET, token.getTokenType());
	}

	@Test
	public void analyzeSymbol_SymbolIsLeftBracket() {
		state.analyzeSymbol('(');

		Assert.assertEquals(1, tokens.size());
		Token token = tokens.get(0);
		Assert.assertEquals("(", token.getContent());
		Assert.assertEquals(TokenType.LEFT_BRACKET, token.getTokenType());
	}
}
